#ifndef DATA_SQL_H_
#define DATA_SQL_H_

#define sql_create_table_instruments		 \
"create table if not exists instruments"	 \
	"(InstrumentID char(31),"				 \
	"ExchangeID char(9),"					 \
	"InstrumentName char(21),"				 \
	"ExchangeInstID char(31),"				 \
	"ProductID char(31),"					 \
	"ProductClass int,"						 \
	"DeliveryYear int,"						 \
	"DeliveryMonth int,"					 \
	"MaxMarketOrderVolume int,"				 \
	"MinMarketOrderVolume int,"				 \
	"MaxLimitOrderVolume int,"				 \
	"MinLimitOrderVolume int,"				 \
	"VolumeMultiple int,"					 \
	"PriceTick double,"						 \
	"CreateDate char(9),"					 \
	"OpenDate char(9),"						 \
	"ExpireDate char(9),"					 \
	"StartDelivDate char(9),"				 \
	"EndDelivDate char(9),"					 \
	"InstLifePhase int,"					 \
	"IsTrading int,"						 \
	"PositionType int,"						 \
	"PositionDateType int,"					 \
	"LongMarginRatio double,"				 \
	"ShortMarginRatio double,"				 \
	"Primary Key(InstrumentID,ExchangeID))"

#define sql_create_code_table				 \
	"create table if not exists code_table"	 \
	"(InstrumentID char(31),"				 \
	"InstrumentName char(21),"				 \
	"InstrumentType int"					 \
	"ShortName char(21),"					 \
	"NameEnu char(21))"

#define sql_create_table_report				  \
	"create table if not exists %1%("		  \
	 "InstrumentID char(31),"				  \
	 "ExchangeID char(9),"					  \
	 "TradingDay char(9),"					  \
	 "TradingTime int,"						  \
	 "TradingMillisec int,"					  \
	 "PreClosePrice double,"				  \
	 "OpenPrice double,"					  \
	 "ClosePrice double,"					  \
	 "HighestPrice double,"					  \
	 "LowestPrice double,"					  \
	 "LastPrice double,"					  \
	 "AveragePrice double,"					  \
	 "CurrDelta double,"					  \
	 "PreDelta double,"						  \
	 "PreSettlementPrice double,"			  \
	 "SettlementPrice double,"				  \
	 "UpperLimitPrice double,"				  \
	 "LowerLimitPrice double,"				  \
	 "OpenInterest double,"					  \
	 "Volume double,"						  \
	 "Turnover double,"						  \
	 "BidPrice1 double,"					  \
	 "BidVolume1 int,"						  \
	 "AskPrice1 double,"					  \
	 "AskVolume1 int)"

#define  sql_create_minute				 \
	"create table if not exists %1%("	 \
	 "InstrumentID char(31),"			 \
	 "ExchangeID char(31),"				 \
	 "InstrumentName char(31),"			 \
	 "LastPrice double,"				 \
	 "HighestPrice double,"				 \
	 "LowestPrice double,"				 \
	 "Volume BIGINT,"					 \
	 "Turnover double,"					 \
	 "UpdateTime int,"					 \
	 "UpdateMillisec int)"
#define sql_create_exchange \
"create table if not exists exchanges(" \
	"ExchangeID char(16)," \
	"ExchangeName char(32)," \
	"ExchangeProperty int," \
	"Primary Key(ExchangeID))"

#define sql_begin_transaction "begin transaction;"

#define sql_commit_transaction "commit transaction;"



typedef bool (*SqliteRowFunc) (sqlite3_stmt* stmt, void* data);

inline sqlite3_stmt*
sqlite_query_prepare(sqlite3* db, const char* sql)
{
	sqlite3_stmt* stmt = NULL;
	int result;

	result = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);

	if (result != SQLITE_OK) {
		const char* str = sqlite3_errmsg(db);
		//throw sqlite_error(str ? str : "unknown error");

		return NULL;
	}

	return stmt;
}

inline int sqlite_query_exec(sqlite3* db, const char* sql)
{
	char* errmsg = NULL;
	int result;

	result = sqlite3_exec(db, sql, NULL, NULL, &errmsg);

	if (result != SQLITE_OK) {
		if (errmsg != NULL) {
			sqlite3_free(errmsg);
		}
		return -1;
	}
	return 0;
}

inline int sqlite_foreach_selected_row(sqlite3* db, const char* sql,
	SqliteRowFunc callback, void* data)
{
	sqlite3_stmt* stmt = NULL;
	int result;
	int n_rows = 0;

	stmt = sqlite_query_prepare(db, sql);
	if (!stmt) {
		return -1;
	}

	while (1) {
		result = sqlite3_step(stmt);

		if (result != SQLITE_ROW)
			break;

		if (callback && !callback(stmt, data))
			break;
		else
		{
			n_rows++;
		}
	}

	if (result == SQLITE_ERROR) {
		sqlite3_finalize(stmt);
		return -1;
	}

	sqlite3_finalize(stmt);
	return n_rows;
}
#endif